import { TemplatesModel } from '@/models/templates.model';
import { Inject, Injectable } from '@nestjs/common';
import { InjectConnection, InjectModel } from '@nestjs/sequelize';
import { TemplatesDto } from './dto';
import { Op, QueryTypes, Sequelize } from 'sequelize';
import { Sequelize as SequelizeTs } from 'sequelize-typescript';

import { JobTemplatesModel } from '@/models/jobTemplates.model';
import { DownloadLog } from '@/models/downloadLog.model';
import { REQUEST } from '@nestjs/core';
import axios from 'axios';
// import axios from 'axios';
const templatesMap = new Map();
@Injectable()
export class TemplateService {
  constructor(
    @InjectModel(TemplatesModel)
    private readonly templatesModel: typeof TemplatesModel,

    @InjectModel(JobTemplatesModel)
    private readonly jobTemplatesModel: typeof JobTemplatesModel,

    @InjectConnection('resume')
    private sequelize: SequelizeTs,

    @InjectModel(DownloadLog)
    private readonly downloadLog: typeof DownloadLog,

    @Inject(REQUEST)
    private readonly request: Request & { user: { userId: number } },
  ) {}
  async addTemplates(params: TemplatesDto): Promise<any> {
    await this.templatesModel.create({ ...params });
    return true;
  }
  async updateTemplates(params: TemplatesDto): Promise<any> {
    await this.templatesModel.update(
      { ...params },
      {
        where: {
          id: params.id,
        },
      },
    );
    return true;
  }

  async getTemplates({ order_by }): Promise<any> {
    try {
      const templates = await this.templatesModel.findAll({
        attributes: { exclude: ['created_time', 'updated_time'] },
        order: [[order_by || 'order', 'DESC']],
      });
      return templates?.map((item) => {
        return {
          ...item.dataValues,
          customization: {
            ...item.customization,
            template: item.dataValues.templateName,
          },
        };
      });
    } catch (e) {
      console.log(e);
    }
  }
  async getTemplatesByClassify({ order_by, classify }): Promise<any> {
    const cf = classify ? +classify : 0;
    try {
      let where = {};
      if (cf) {
        where = {
          status: 1,
          [Op.and]: Sequelize.literal(`classify & ${cf} > 0`),
        };
      } else {
        where = {
          status: 1,
        };
      }
      const templates = await this.templatesModel.findAll({
        attributes: { exclude: ['created_time', 'updated_time'] },
        order: [[order_by || 'order', 'DESC']],
        where,
      });
      return templates?.map((item) => {
        return {
          ...item.dataValues,
          customization: {
            ...item.customization,
            template: item.dataValues.templateName,
          },
        };
      });
    } catch (e) {
      console.log(e);
    }
  }
  async getTemplateById({ id }): Promise<any> {
    const where: any = {};
    if (id) {
      where.id = id;
    } else {
      where.default = 1;
    }
    const template = await this.templatesModel.findOne({
      attributes: {
        exclude: ['created_time', 'updated_time'],
      },

      where: where,
    });

    const result = {
      personalDetails: template?.personalDetails || {},
      content: template?.content || {},
      customization: {
        ...(template?.customization || {}),
        template:
          template?.templateName ||
          (template?.customization as any)?.template ||
          'tpl1',
        templateId: template?.id,
        sectionOrder: (template?.customization as any)?.sectionOrder || {},
      },
    };
    if (id) {
    }
    return result;
  }
  async getTemplate(where): Promise<any> {
    const template = await this.templatesModel.findOne({
      attributes: {
        exclude: ['created_time', 'updated_time'],
      },
      where: where,
    });
    const result = {
      personalDetails: template.personalDetails || {},
      content: template.content || {},
      customization: {
        ...template.customization,
        template:
          template.templateName || (template.customization as any).template,
        templateId: template.id,
        sectionOrder: (template.customization as any)?.sectionOrder || {},
        // defaultSectionOrder:
        //   (template.customization as any)?.defaultSectionOrder || {},
      },
      // templateName: template.templateName,
    };

    return result;
  }
  async getTemplateByName(name): Promise<TemplatesModel> {
    if (templatesMap.has(name)) {
      return JSON.parse(templatesMap.get(name));
    }

    const template = await this.templatesModel.findOne({
      attributes: { exclude: ['created_time', 'updated_time'] },
      where: {
        templateName: name,
      },
    });
    if (name) {
      // templatesMap.set(name, JSON.stringify(template));
    }
    return template;
  }
  async getTemplateByMid({ id }): Promise<any> {
    const where: any = {};
    if (id) {
      where.id = id;
    } else {
      where.default = 1;
    }
    const template: any = await this.templatesModel.findOne({
      attributes: {
        exclude: ['created_time', 'updated_time'],
      },

      where: where,
    });

    const result = {
      personalDetails: template?.personalDetails || {},
      content: template?.content || {},
      customization: {
        ...(template?.customization || {}),
        template:
          template?.templateName ||
          (template?.customization as any)?.template ||
          'tpl1',
        templateId: template?.id,
        sectionOrder: (template?.customization as any)?.sectionOrder || {},
      },
      title: template?.title,
      description: template?.description,
      templateName:
        template?.templateName ||
        (template?.customization as any)?.template ||
        'tpl1',
      order: template?.order,
      default: template?.default,
      show: template?.show,
      classify: template?.classify,
    };
    if (id) {
    }
    return result;
  }

  async updateStatus(params): Promise<any> {
    await this.templatesModel.update(
      { ...params },
      {
        where: {
          id: params.id,
        },
      },
    );
    return true;
  }
  async tempDel(params): Promise<any> {
    await this.templatesModel.destroy({
      where: {
        id: params.id,
      },
    });
    return true;
  }
  async getCvTempList({ pageSize, pageNum }): Promise<any> {
    try {
      const { rows, count } = await this.jobTemplatesModel.findAndCountAll({
        attributes: ['id', 'title', 'description', 'templateUrl'],
        where: {},
        limit: +pageSize || 10, // 确保是 number 类型
        offset: (+pageNum - 1) * (+pageSize || 10), // 计算偏移量算法
      });
      return { total: count, list: rows };
    } catch (e) {}
  }
  async getCvTemp({ id }): Promise<any> {
    const where: any = {};
    if (id) {
      where.id = id;
    }
    const jobTemplate = await this.jobTemplatesModel.findOne({
      attributes: {
        exclude: ['created_time', 'updated_time'],
      },
      where: where,
    });
    if (jobTemplate?.tempId) {
      const template: any = await this.templatesModel.findOne({
        attributes: {
          include: ['customization'],
        },
        where: {
          id: jobTemplate?.tempId,
        },
      });
      const result = {
        personalDetails: jobTemplate?.personalDetails || {},
        content: jobTemplate?.content || {},
        customization: {
          ...(template?.customization || {}),
          template:
            template?.templateName ||
            (template?.customization as any)?.template ||
            'tpl1',
          templateId: template?.id,
          sectionOrder: (template?.customization as any)?.sectionOrder || {},
        },
        title: jobTemplate?.title,
        description: jobTemplate?.description,
        templateUrl: jobTemplate?.templateUrl,
      };
      return result;
    }
    return null;
  }

  async getWordTemplate(params) {
    const { pageNum, pageSize } = params;
    const sql = `select id, template_name,template_img  from  word_template_list where flag=1   ORDER BY id desc limit ${
      +pageSize * (+pageNum - 1)
    } , ${200} `;

    const sql2 = ` SELECT COUNT(id) AS TOTAL FROM word_template_list where flag=1;`;
    const total = await this.sequelize.query(sql2, {
      type: QueryTypes.SELECT,
    });
    const result = await this.sequelize.query(sql, {
      type: QueryTypes.SELECT,
    });
    const urls = result.map((r: any) => {
      return `<url>
        <loc>https://www.jianli101.com/word/${r.id}</loc>
        <lastmod>2024-07-23</lastmod>
        <priority>1</priority>
       </url>`;
    });
    console.log(urls.join('\n'));

    return {
      total: total[0]?.['TOTAL'],
      data: result,
    };
  }
  async getWordTemplateById(params) {
    const { id } = params;
    const sql = `select id, template_name,template_img  from  word_template_list where flag=1 and id = ${id};`;

    const result = await this.sequelize.query(sql, {
      type: QueryTypes.SELECT,
    });
    return result[0] || {};
  }

  async addDownloadLog({ userId, previewUrl }) {
    try {
      await this.downloadLog.create({
        userId,
        previewUrl: previewUrl,
      });
    } catch (e) {}
    return true;
  }
  async downloadWord(params) {
    const { id } = params;

    const sql = `select download_url  from  word_template_list where flag=1 and id = ${id};`;

    const result: any = await this.sequelize.query(sql, {
      type: QueryTypes.SELECT,
    });
    try {
      await this.addDownloadLog({
        userId: this.request.user?.userId || null,
        previewUrl: result[0]?.download_url,
      });
    } catch (e) {}
    const res = await axios.get(result[0]?.download_url, {
      responseType: 'arraybuffer',
    });

    return res.data;
  }
}
